<template>
  <div class="login-container">
    <!-- 顶部 -->
    <div class="absolute-lt flex-x-end p-3 w-full">
      <el-switch
          v-model="isDark"
          inline-prompt
          active-icon="Moon"
          inactive-icon="Sunny"
          @change="toggleTheme"
      />
      <lang-select class="ml-2 cursor-pointer"/>
    </div>
    <!-- 登录表单 -->
    <el-card class="!border-none  !rounded-4% w-100 <sm:w-85">
      <div class="text-center relative">
        <h2>{{ defaultSettings.title }}</h2>
        <el-tag class="ml-2 absolute-rt">{{ defaultSettings.version }}</el-tag>
      </div>

      <el-form
          ref="loginFormRef"
          :model="loginData"
          :rules="loginRules"
          class="login-form"
      >
        <el-form-item v-if="loginData.loginWay === 'phone'" prop="phoneNumber">
          <div class="flex-y-center w-full">
            <el-input
                v-model="loginData.phoneNumber"
                @keyup.enter="handleLogin"
                :placeholder="$t('login.phoneNumber')"
                class="height: 100%;"
            >
              <template #prepend>
                <el-select v-model="loginData.areaCode" size="large" style="width: 85px;height: 100%;">
                  <el-option label="(+86) 中国" value="+86"/>
                  <el-option label="(+852) 中国香港" value="+852"/>
                  <el-option label="(+853) 中国澳门" value="+853"/>
                  <el-option label="(+886) 中国台湾" value="+886"/>
                  <template #prefix>
                    <span>{{loginData.areaCode}}</span>
                  </template>
                </el-select>
                <el-divider direction="vertical" style="margin: 0 0 0 12px"/>
              </template>
            </el-input>
          </div>
        </el-form-item>

        <el-form-item v-if="loginData.loginWay === 'phone'" prop="verificationCode">
          <div class="flex-y-center w-full">
            <el-input
                v-model="loginData.verificationCode"
                @keyup.enter="handleLogin"
                :placeholder="$t('login.verificationCode')"
                input-style="height:38px;padding-left:16px"
            >
              <template #append>
                <el-button text link size="default" style="padding: 0 16px;" @click="openPuzzleCheck">{{
                  $t("login.getVerificationCode")}}
                </el-button>
              </template>
            </el-input>
          </div>
        </el-form-item>

        <!-- 用户名 -->
        <el-form-item v-if="loginData.loginWay === 'account'" prop="username">
          <div class="flex-y-center w-full">
            <svg-icon icon-class="user" class="mx-2"/>
            <el-input
                ref="username"
                v-model="loginData.username"
                :placeholder="$t('login.username')"
                name="username"
                size="large"
                class="h-[38px]"
            />
          </div>
        </el-form-item>

        <!-- 密码 -->
        <el-tooltip v-if="loginData.loginWay === 'account'"
                    :visible="isCapslock"
                    :content="$t('login.capsLock')"
                    placement="right"
        >
          <el-form-item prop="password">
            <div class="flex-y-center w-full">
              <svg-icon icon-class="lock" class="mx-2"/>
              <el-input
                  v-model="loginData.password"
                  :placeholder="$t('login.password')"
                  type="password"
                  name="password"
                  @keyup="checkCapslock"
                  @keyup.enter="handleLogin"
                  size="large"
                  class="h-[38px] pr-2"
                  show-password
              />
            </div>
          </el-form-item>
        </el-tooltip>

        <!-- 验证码 -->
        <el-form-item v-if="loginData.loginWay === 'account'" prop="captcha">
          <div class="flex-y-center w-full">
            <svg-icon icon-class="captcha" class="mx-2"/>
            <el-input
                v-model="loginData.captcha"
                auto-complete="off"
                size="large"
                class="flex-1"
                :placeholder="$t('login.captchaCode')"
                @keyup.enter="handleLogin"
            />

            <el-image
                @click="refreshCaptcha"
                :src="captchaBase64"
                class="rounded-tr-md rounded-br-md cursor-pointer h-[38px]"
            >
            </el-image>
          </div>
        </el-form-item>

        <!-- 登录按钮 -->
        <el-button
            :loading="loading"
            :disabled="loginButtonStatus"
            type="primary"
            size="large"
            class="w-full"
            @click.prevent="handleLogin"
        >{{ $t("login.login") }}
        </el-button>

        <!-- 账号密码提示 -->
        <div class="mt-10 text-sm">
          <el-button text link size="default" style="color: #8c939d" @click.prevent="changeLoginWay">
            {{loginData.loginWay === 'account'?$t("login.phoneSignIn"):$t("login.accountSignIn")}}
          </el-button>
          <!--          <span v-if="loginData.loginWay === 'account'" style="color: #8c939d">-->
          <!--             <span class="ml-4"> {{ $t("login.password") }}: 初始密码是123456</span>-->
          <!--          </span>-->
        </div>
      </el-form>
    </el-card>
    <div v-show="verificationVisible"
         style=" position: fixed;top: 0;left: 0;width: 100%;height: 100%;background: rgba(0, 0, 0, 0.5); z-index: 1000;display: grid;place-items: center;height: 100vh; ">
      <PuzzleVerification
          v-model="verificationVisible"
          :onSuccess="puzzleSuccess"
          blockType="puzzle"
          :puzzleImgList="puzzleImage"
      />
    </div>

    <el-dialog
        v-model="userSelectDialogVisible"
        title="选择登录用户"
        width="350"

    >
      <div
          style="width: 100%; max-height: 280px;overflow-x: hidden;overflow-y: auto !important;-ms-overflow-y:auto !important;text-align: center;">
        <div class="flex flex-wrap" v-for="item in userSelectList" :key="item">
          <el-card class="user-select-card" shadow="always" @click=selectedUserClick(item)>
            <el-icon style="vertical-align: text-top;margin: 0px 6px">
              <UserFilled/>
            </el-icon>
            {{ getUserName(item) }}
          </el-card>
        </div>
      </div>
    </el-dialog>

    <!-- ICP备案 -->
    <div class="absolute bottom-1 text-center" v-show="icpVisible" style="font-size: small;color: lightgrey">
      <p>
        Copyright © {{currentYear}} xxxx公司 版权所有
      </p>
      <a target="_blank" href="http://www.beian.gov.cn/portal/registerSystemInfo?recordcode=xxxx" >
        <img src="@/assets/images/beianbgs.png" style="width: 20px; height: 20px; margin-right: 10px; vertical-align: middle; ">沪公网安备 xxxx号</a>
      <a style="margin-left: 20px" href="http://beian.miit.gov.cn/" target="_blank">沪ICP备xxxx号-1</a>
    </div>
  </div>
</template>

<script setup lang="ts">
import {useSettingsStore, useUserStore} from "@/store";
import AuthAPI from "@/api/auth";
import {LoginData} from "@/api/auth/model";
import {randomStrByLenAndDate} from "@/utils/common";
import {FormInstance, ElMessage} from "element-plus";
import {LocationQuery, LocationQueryValue, useRoute} from "vue-router";
import router from "@/router";
import defaultSettings from "@/settings";
import {ThemeEnum} from "@/enums/ThemeEnum";
import {tr} from "element-plus/es/locale";
import {X_KEY_SM2} from "@/enums/CacheEnum";

// Stores
const userStore = useUserStore();
const settingsStore = useSettingsStore();

// Internationalization
const {t} = useI18n();

// Reactive states
const isDark = ref(settingsStore.theme === ThemeEnum.DARK);
const icpVisible = ref(true);
const loading = ref(false); // 按钮loading
const isCapslock = ref(false); // 是否大写锁定
const captchaBase64 = ref(); // 验证码图片Base64字符串
const loginFormRef = ref<FormInstance>(); // 登录表单ref
const {height} = useWindowSize();
const randomStr = ref();
const verificationVisible = ref(false); //
const userSelectDialogVisible = ref(false);
const userSelectList = ref([]);
const loginButtonStatus = ref(false); //登录按钮不可编辑状态

const currentYear = new Date().getFullYear();


const puzzleImage = ref(
    [new URL('@/verification/assets/thumbnail-img01.jpg', import.meta.url),
      new URL('@/verification/assets/thumbnail-img02.jpg', import.meta.url),
      new URL('@/verification/assets/thumbnail-img03.jpg', import.meta.url)
    ]);

const loginData = ref<LoginData>({
  username: "",
  password: "",
  areaCode: "+86",
  phoneNumber: "",
  verificationCode: "",
  loginWay: "account",
  phoneUserId: "",
});

const loginRules = computed(() => {
  return {
    username: [
      {
        required: loginData.value.loginWay === 'account',
        trigger: "blur",
        message: t("login.message.username.required"),
      },
    ],
    password: [
      {
        required: loginData.value.loginWay === 'account',
        trigger: "blur",
        message: t("login.message.password.required"),
      },
      {
        min: 6,
        message: t("login.message.password.min"),
        trigger: "blur",
      },
    ],
    captcha: [
      {
        required: loginData.value.loginWay === 'account',
        trigger: "blur",
        message: t("login.message.captchaCode.required"),
      },
    ],
    phoneNumber: [
      {
        required: loginData.value.loginWay === 'phone',
        trigger: "blur",
        message: t("login.message.phoneNumber.required"),
      },
      {
        pattern: /^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\d{8}$/,
        message: t("login.message.phoneNumber.patternMsg"),
      },
    ],
    verificationCode: [
      {
        required: loginData.value.loginWay === 'phone',
        trigger: "blur",
        message: t("login.message.verificationCode.required"),
      },
    ],
  };
});

/** 登录 */
const route = useRoute();

/** 获取验证码 */
function getCaptcha(randomStr: string) {
  AuthAPI.getCaptcha(randomStr).then((response) => {
    loginData.value.randomStr = randomStr;
    sessionStorage.setItem(X_KEY_SM2, response.data.puk);
    captchaBase64.value = response.data.captcha;
  });
}

function refreshCaptcha() {
  const randKey = randomStrByLenAndDate(6, true);
  randomStr.value = randKey;
  getCaptcha(randKey);
}

function changeLoginWay() {
  if (loginData.value.loginWay === 'phone') {
    refreshCaptcha();
    loginData.value.loginWay = 'account'
    loginButtonStatus.value = false; //登录按钮状态变为可点击
  } else if (loginData.value.loginWay === 'account') {
    loginData.value.loginWay = 'phone'
    loginButtonStatus.value = true; //登录按钮状态变为不可点击
  }
  // nextTick(()=>{
  //   loginFormRef.value?.clearValidate();
  // })
}

function openPuzzleCheck() {
  //校验一下手机号
  loginFormRef.value?.validateField('phoneNumber', (errorMessage) => {
    if (errorMessage) {
      verificationVisible.value = true;
    }
  });
}

//图片拼图验证成功
const puzzleSuccess = () => {
  verificationVisible.value = false;
  loginButtonStatus.value = false; //登录按钮状态变为可点击
  getVerificationCode();
};

/**
 * 获取短信验证码
 */
function getVerificationCode() {
  loginData.value.phoneUserId = "";

  AuthAPI.sendSMS(loginData.value.randomStr, loginData.value.phoneNumber || '').then((response) => {
    if (response.status) {
      ElMessage({
        message: response.data.resMsg,
        type: 'success',
      })
    }
  });
}

function getLoginUser() {
  AuthAPI.smsCheck(loginData.value.randomStr, loginData.value.phoneNumber, loginData.value.verificationCode).then((response) => {
    if (response.status) {
      if (response.data.length > 1) {
        userSelectList.value = response.data;
        userSelectDialogVisible.value = true;
      } else if (response.data.length == 1) {
        //只有一个用户，直接登录
        loginData.value.phoneUserId = response.data[0].split("-")[0];
        handleLogin();
      } else {
        ElMessage({
          message: "账户异常",
          type: 'error',
        })
      }
    }
  });
}

function handleLogin() {
  if (!loading.value) {
    loginFormRef.value?.validate((valid: boolean) => {
      if (valid) {
        if ('phone' == loginData.value.loginWay) {
          if (loginData.value.phoneUserId == "") {
            //去校验获取用户列表
            getLoginUser();
            return;
          }
        }
        loading.value = true;
        userStore
            .login(loginData.value)
            .then(() => {
              const query: LocationQuery = route.query;
              const redirect = (query.redirect as LocationQueryValue) ?? "/";
              const otherQueryParams = Object.keys(query).reduce(
                  (acc: any, cur: string) => {
                    if (cur !== "redirect") {
                      acc[cur] = query[cur];
                    }
                    return acc;
                  },
                  {}
              );

              router.push({path: redirect, query: otherQueryParams});
            })
            .catch(() => {
              refreshCaptcha();
              loading.value = false;
            })
            .finally(() => {
            });
      }
    });
  }
}

function selectedUserClick(user: string) {
  loginData.value.phoneUserId = user.split("-")[0];
  userSelectDialogVisible.value = false;
  ElMessage('正在登录...')
  //自动触发登录
  handleLogin();

}

/** 主题切换 */
const toggleTheme = () => {
  const newTheme =
      settingsStore.theme === ThemeEnum.DARK ? ThemeEnum.LIGHT : ThemeEnum.DARK;
  settingsStore.changeTheme(newTheme);
};

/** 根据屏幕宽度切换设备模式 */
watchEffect(() => {
  if (height.value < 600) {
    icpVisible.value = false;
  } else {
    icpVisible.value = true;
  }
});

/** 检查输入大小写 */
function checkCapslock(event: KeyboardEvent) {
  // 防止浏览器密码自动填充时报错
  if (event instanceof KeyboardEvent) {
    isCapslock.value = event.getModifierState("CapsLock");
  }
}

/** 获取验证码 */
function getUserName(user: string) {
  return user.split("-")[1];
}


onMounted(() => {
  refreshCaptcha()
});
</script>

<style lang="scss" scoped>
html.dark .login-container {
  background: url("@/assets/images/login-bg-dark.jpg") no-repeat center right;
}

.login-container {
  overflow-y: auto;
  background: url("./images/login_bg.jpg") no-repeat;
  background-size: cover; /* 设置背景图片大小以覆盖整个元素 */
  background-position: center; /* 背景图片居中显示 */
  background-attachment: fixed; /* 背景图片固定，不随页面滚动 */

  @apply wh-full flex-center;

  .login-form {
    padding: 30px 10px;
  }
}

.el-form-item {
  background: var(--el-input-bg-color);
  border: 1px solid var(--el-border-color);
  border-radius: 5px;
}

/*
手机号区号选择器
 */
:deep(.login-form .el-input-group__prepend) {
  background: unset;
  box-shadow: none;
}

:deep(.login-form .el-input-group__prepend .el-select__wrapper) {
  box-shadow: none;
}


/*
获取验证码文字按钮区域
 */
:deep(.login-form .el-input-group__append) {
  background: unset;
  box-shadow: none;
}

/*
隐藏选中的内容，因为改用插槽的方式实现，会和原来的重合
 */
:deep(.login-form .el-select .el-select__selection,.el-select__selected-item) {
  display: none;
}

/**
选中的显示内容
 */
:deep(.login-form .el-select .el-select__prefix) {
  width: 30px;
}

.user-select-card:hover {
  transform: scale(1.05); /* 放大1.1倍 */
  border-color: #337afd; /* 鼠标悬停时的边框颜色 */
}

/* 鼠标按下时的样式 */
.user-select-card:active {
  background-color: #d0d0d0; /* 鼠标按下时的背景颜色 */
  border-color: #999; /* 鼠标按下时的边框颜色 */
}

.user-select-card {
  width: 95%;
  margin: 4px auto;
  text-align: center;
  font-size: larger;
}

:deep(.user-select-card .el-card__body) {
  padding: 14px;
}


:deep(.el-input) {
  .el-input__wrapper {
    padding: 0;
    background-color: transparent;
    box-shadow: none;

    &.is-focus,
    &:hover {
      box-shadow: none !important;
    }

    input:-webkit-autofill {
      /* 通过延时渲染背景色变相去除背景颜色 */
      transition: background-color 1000s ease-in-out 0s;
    }
  }
}
</style>
